/*
 * Borad.c
 *
 *  Created on: Sep 10, 2012
 *      Author: Larry.Li
 */
#include <stdio.h>
#include <stdlib.h>
#include "BitBoard.h"
#include "BitBoardOps.h"

//if the chesses position bits(j) is not valid( the current cell should have chess)
#define BITS_POSITION_NOT_VALID(bitsPosition,bitPosition) (bitsPosition & bitMask[bitPosition]) == 0

BitBoard mask[90];
BitBoard rotateMask[90];

const unsigned long bitMask[] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
		0x100, 0x200 };
const BitBoard fileMask[] = { { .startingBits = 0x1 },
		{ .startingBits = 0x200 }, { .startingBits = 0x40000 }, {
				.startingBits = 0x8000000 }, { .middleBits = 0x10 }, {
				.middleBits = 0x2000 }, { .middleBits = 0x400000 }, {
				.middleBits = 0x80000000 }, { .endingBits = 0x100 }, {
				.endingBits = 0x20000 } };
const int indexRowMapping[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
		4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
		7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
		9, 9 };
const int indexRotatedRowMapping[] = { 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4,
		3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7,
		6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1,
		0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4,
		3, 2, 1, 0 };
const int indexRankBitsPositionMapping[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2,
		3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5,
		6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2,
		3, 4, 5, 6, 7, 8 };

ChessPosition chessPosition;

PieceMovements MOVEMENTS;

void initJiangMovements() {

	BITBOARD_OR(MOVEMENTS.jiang[3], mask[4]);
	BITBOARD_OR(MOVEMENTS.jiang[3], mask[12]);

	BITBOARD_OR(MOVEMENTS.jiang[4], mask[3]);
	BITBOARD_OR(MOVEMENTS.jiang[4], mask[5]);
	BITBOARD_OR(MOVEMENTS.jiang[4], mask[13]);

	BITBOARD_OR(MOVEMENTS.jiang[5], mask[4]);
	BITBOARD_OR(MOVEMENTS.jiang[5], mask[14]);

	BITBOARD_OR(MOVEMENTS.jiang[12], mask[3]);
	BITBOARD_OR(MOVEMENTS.jiang[12], mask[13]);
	BITBOARD_OR(MOVEMENTS.jiang[12], mask[21]);

	BITBOARD_OR(MOVEMENTS.jiang[13], mask[4]);
	BITBOARD_OR(MOVEMENTS.jiang[13], mask[12]);
	BITBOARD_OR(MOVEMENTS.jiang[13], mask[14]);
	BITBOARD_OR(MOVEMENTS.jiang[13], mask[22]);

	BITBOARD_OR(MOVEMENTS.jiang[14], mask[5]);
	BITBOARD_OR(MOVEMENTS.jiang[14], mask[13]);
	BITBOARD_OR(MOVEMENTS.jiang[14], mask[23]);

	BITBOARD_OR(MOVEMENTS.jiang[21], mask[12]);
	BITBOARD_OR(MOVEMENTS.jiang[21], mask[22]);

	BITBOARD_OR(MOVEMENTS.jiang[22], mask[21]);
	BITBOARD_OR(MOVEMENTS.jiang[22], mask[13]);
	BITBOARD_OR(MOVEMENTS.jiang[22], mask[23]);

	BITBOARD_OR(MOVEMENTS.jiang[23], mask[22]);
	BITBOARD_OR(MOVEMENTS.jiang[23], mask[14]);

	BITBOARD_OR(MOVEMENTS.jiang[66], mask[75]);
	BITBOARD_OR(MOVEMENTS.jiang[66], mask[67]);

	BITBOARD_OR(MOVEMENTS.jiang[67], mask[66]);
	BITBOARD_OR(MOVEMENTS.jiang[67], mask[68]);
	BITBOARD_OR(MOVEMENTS.jiang[67], mask[76]);

	BITBOARD_OR(MOVEMENTS.jiang[68], mask[77]);
	BITBOARD_OR(MOVEMENTS.jiang[68], mask[67]);

	BITBOARD_OR(MOVEMENTS.jiang[75], mask[84]);
	BITBOARD_OR(MOVEMENTS.jiang[75], mask[76]);
	BITBOARD_OR(MOVEMENTS.jiang[75], mask[66]);

	BITBOARD_OR(MOVEMENTS.jiang[76], mask[85]);
	BITBOARD_OR(MOVEMENTS.jiang[76], mask[75]);
	BITBOARD_OR(MOVEMENTS.jiang[76], mask[77]);
	BITBOARD_OR(MOVEMENTS.jiang[76], mask[67]);

	BITBOARD_OR(MOVEMENTS.jiang[77], mask[86]);
	BITBOARD_OR(MOVEMENTS.jiang[77], mask[76]);
	BITBOARD_OR(MOVEMENTS.jiang[77], mask[68]);

	BITBOARD_OR(MOVEMENTS.jiang[84], mask[85]);
	BITBOARD_OR(MOVEMENTS.jiang[84], mask[75]);

	BITBOARD_OR(MOVEMENTS.jiang[85], mask[84]);
	BITBOARD_OR(MOVEMENTS.jiang[85], mask[86]);
	BITBOARD_OR(MOVEMENTS.jiang[85], mask[76]);

	BITBOARD_OR(MOVEMENTS.jiang[86], mask[85]);
	BITBOARD_OR(MOVEMENTS.jiang[86], mask[77]);

}

void initXiangMovements() {
	int i;
	for (i = 0; i < 90; i++) {
		MOVEMENTS.xiangIndexMapping[i] = INVALID_POS;
		MOVEMENTS.xiangGoingTopRowMapping[i] = INVALID_POS;
		MOVEMENTS.xiangGoingBottomRowMapping[i] = INVALID_POS;
	}

	MOVEMENTS.xiangIndexMapping[2] = 0;
	MOVEMENTS.xiangGoingTopRowMapping[2] = 1;
	MOVEMENTS.xiangGoingBottomRowMapping[18] = INVALID_POS;

	MOVEMENTS.xiangIndexMapping[6] = 1;
	MOVEMENTS.xiangGoingTopRowMapping[6] = 1;
	MOVEMENTS.xiangGoingBottomRowMapping[18] = INVALID_POS;

	MOVEMENTS.xiangIndexMapping[18] = 2;
	MOVEMENTS.xiangGoingTopRowMapping[18] = 3;
	MOVEMENTS.xiangGoingBottomRowMapping[18] = 1;

	MOVEMENTS.xiangIndexMapping[22] = 3;
	MOVEMENTS.xiangGoingTopRowMapping[22] = 3;
	MOVEMENTS.xiangGoingBottomRowMapping[22] = 1;

	MOVEMENTS.xiangIndexMapping[26] = 4;
	MOVEMENTS.xiangGoingTopRowMapping[26] = 3;
	MOVEMENTS.xiangGoingBottomRowMapping[26] = 1;

	MOVEMENTS.xiangIndexMapping[38] = 5;
	MOVEMENTS.xiangGoingTopRowMapping[38] = INVALID_POS;
	MOVEMENTS.xiangGoingBottomRowMapping[38] = 3;

	MOVEMENTS.xiangIndexMapping[42] = 6;
	MOVEMENTS.xiangGoingTopRowMapping[42] = INVALID_POS;
	MOVEMENTS.xiangGoingBottomRowMapping[42] = 3;

	MOVEMENTS.xiangIndexMapping[47] = 7;
	MOVEMENTS.xiangGoingTopRowMapping[47] = 6;
	MOVEMENTS.xiangGoingBottomRowMapping[47] = INVALID_POS;

	MOVEMENTS.xiangIndexMapping[51] = 8;
	MOVEMENTS.xiangGoingTopRowMapping[51] = 6;
	MOVEMENTS.xiangGoingBottomRowMapping[51] = INVALID_POS;

	MOVEMENTS.xiangIndexMapping[63] = 9;
	MOVEMENTS.xiangGoingTopRowMapping[63] = 8;
	MOVEMENTS.xiangGoingBottomRowMapping[63] = 6;

	MOVEMENTS.xiangIndexMapping[67] = 10;
	MOVEMENTS.xiangGoingTopRowMapping[67] = 8;
	MOVEMENTS.xiangGoingBottomRowMapping[67] = 6;

	MOVEMENTS.xiangIndexMapping[71] = 11;
	MOVEMENTS.xiangGoingTopRowMapping[71] = 8;
	MOVEMENTS.xiangGoingBottomRowMapping[71] = 6;

	MOVEMENTS.xiangIndexMapping[83] = 12;
	MOVEMENTS.xiangGoingTopRowMapping[83] = INVALID_POS;
	MOVEMENTS.xiangGoingBottomRowMapping[83] = 8;

	MOVEMENTS.xiangIndexMapping[87] = 13;
	MOVEMENTS.xiangGoingTopRowMapping[87] = INVALID_POS;
	MOVEMENTS.xiangGoingBottomRowMapping[87] = 8;

	unsigned long j;

	for (j = 0; j < 512; j++) {
		if ((j & 0x2) == 0) {
			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[2]][j],
					mask[18]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[18]][j],
					mask[2]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[18]][j],
					mask[38]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[38]][j],
					mask[18]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[47]][j],
					mask[63]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[63]][j],
					mask[47]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[63]][j],
					mask[83]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[83]][j],
					mask[63]);
		}
		if ((j & 0x8) == 0) {
			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[2]][j],
					mask[22]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[22]][j],
					mask[2]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[22]][j],
					mask[38]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[38]][j],
					mask[22]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[47]][j],
					mask[67]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[67]][j],
					mask[47]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[67]][j],
					mask[83]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[83]][j],
					mask[67]);
		}
		if ((j & 0x20) == 0) {
			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[6]][j],
					mask[22]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[22]][j],
					mask[6]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[22]][j],
					mask[42]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[42]][j],
					mask[22]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[51]][j],
					mask[67]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[67]][j],
					mask[51]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[67]][j],
					mask[87]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[87]][j],
					mask[67]);
		}
		if ((j & 0x80) == 0) {
			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[6]][j],
					mask[26]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[26]][j],
					mask[6]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[26]][j],
					mask[42]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[42]][j],
					mask[26]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[51]][j],
					mask[71]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[71]][j],
					mask[51]);

			BITBOARD_OR(
					MOVEMENTS.xiangGoingTop[MOVEMENTS.xiangIndexMapping[71]][j],
					mask[87]);
			BITBOARD_OR(
					MOVEMENTS.xiangGoingBottom[MOVEMENTS.xiangIndexMapping[87]][j],
					mask[71]);
		}
	}
}

void initShiMovement() {
	BITBOARD_OR(MOVEMENTS.shi[3], mask[13]);

	BITBOARD_OR(MOVEMENTS.shi[5], mask[13]);

	BITBOARD_OR(MOVEMENTS.shi[13], mask[3]);
	BITBOARD_OR(MOVEMENTS.shi[13], mask[21]);
	BITBOARD_OR(MOVEMENTS.shi[13], mask[23]);
	BITBOARD_OR(MOVEMENTS.shi[13], mask[5]);

	BITBOARD_OR(MOVEMENTS.shi[21], mask[13]);

	BITBOARD_OR(MOVEMENTS.shi[23], mask[13]);

	BITBOARD_OR(MOVEMENTS.shi[84], mask[76]);

	BITBOARD_OR(MOVEMENTS.shi[86], mask[76]);

	BITBOARD_OR(MOVEMENTS.shi[76], mask[84]);
	BITBOARD_OR(MOVEMENTS.shi[76], mask[86]);
	BITBOARD_OR(MOVEMENTS.shi[76], mask[66]);
	BITBOARD_OR(MOVEMENTS.shi[76], mask[68]);

	BITBOARD_OR(MOVEMENTS.shi[66], mask[76]);

	BITBOARD_OR(MOVEMENTS.shi[68], mask[76]);

}

void initRedBingMovement() {
	int i;
	for (i = 27; i < 90; i++) {
		int bitPosition = indexRankBitsPositionMapping[i];
		if (i >= 45) {
			if (bitPosition != 0) {
				BITBOARD_OR(MOVEMENTS.r_bing[i], mask[i-1]);
			}
			if (bitPosition != 8) {
				BITBOARD_OR(MOVEMENTS.r_bing[i], mask[i+1]);
			}
		}
		if (i < 81) {
			BITBOARD_OR(MOVEMENTS.r_bing[i], mask[i+9]);
		}
	}
}

void initBlackBingMovement() {
	int i;
	for (i = 62; i >= 0; i--) {
		int bitPosition = indexRankBitsPositionMapping[i];
		if (i <= 44) {
			if (bitPosition != 0) {
				BITBOARD_OR(MOVEMENTS.b_bing[i], mask[i-1]);
			}
			if (bitPosition != 8) {
				BITBOARD_OR(MOVEMENTS.b_bing[i], mask[i+1]);
			}
		}
		if (i > 8) {
			BITBOARD_OR(MOVEMENTS.b_bing[i], mask[i-9]);
		}
	}
}

void initBingMovement() {
	initRedBingMovement();
	initBlackBingMovement();
}

void initCheMovement() {
	int i, k;
	unsigned long j, lowerBits, thisBitMask;
	//rank attack
	for (i = 0; i < 9; i++) {
		for (j = 0; j < 512; j++) {
			int bitPosition = i;

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			int bitsToRightBorder = bitPosition;
			int bitsToLeftBorder = 8 - bitsToRightBorder;

			lowerBits = j;
			//looking leftward
			int accessable = 1;
			while (bitsToLeftBorder > 0) {
				thisBitMask = bitMask[9 - bitsToLeftBorder];
				if (accessable) {
					if ((lowerBits & thisBitMask) != 0) {
						accessable = 0;
					}
					lowerBits |= thisBitMask;
				} else {
					lowerBits &= ~thisBitMask;
				}

				bitsToLeftBorder--;
			}

			//looking rightward
			accessable = 1;
			while (bitsToRightBorder > 0) {
				thisBitMask = bitMask[bitsToRightBorder - 1];
				if (accessable) {
					if ((lowerBits & thisBitMask) != 0) {
						accessable = 0;
					}
					lowerBits |= thisBitMask;
				} else {
					lowerBits &= ~thisBitMask;
				}
				bitsToRightBorder--;
			}
			lowerBits &= ~bitMask[bitPosition];
			for (k = 0; k < 10; k++) {
				MOVEMENTS.cheRank[i + k * 9][j].startingBits = lowerBits;
				bitBoardLeftShift(&MOVEMENTS.cheRank[i + k * 9][j], k * 9);
			}
		}
	}

	//file attack
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 1024; j++) {
			int bitPosition = i;

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			int bitsToBottomBorder = bitPosition;
			int bitsToTopBorder = 9 - bitsToBottomBorder;

			lowerBits = j;
			//looking leftward
			int accessable = 1;
			while (bitsToTopBorder > 0) {
				thisBitMask = bitMask[10 - bitsToTopBorder];
				if (accessable) {
					if ((lowerBits & thisBitMask) != 0) {
						accessable = 0;
					}
					lowerBits |= thisBitMask;
				} else {
					lowerBits &= ~thisBitMask;
				}
				bitsToTopBorder--;
			}

			//looking rightward
			accessable = 1;
			while (bitsToBottomBorder > 0) {
				thisBitMask = bitMask[bitsToBottomBorder - 1];
				if (accessable) {
					if ((lowerBits & thisBitMask) != 0) {
						accessable = 0;
					}
					lowerBits |= thisBitMask;
				} else {
					lowerBits &= ~thisBitMask;
				}
				bitsToBottomBorder--;
			}
			lowerBits &= ~bitMask[bitPosition];
			for (k = 0; k < 9; k++) {
				MOVEMENTS.cheFile[i * 9 + k][j] =
						getFileBitBoardFromLowest10Bits(lowerBits, k);
			}
		}
	}
}

void initMaMovement() {
	int i, bitPosition;
	unsigned long j;
	for (i = 0; i < 90; i++) {
		bitPosition = indexRankBitsPositionMapping[i];
		//rank movement
		for (j = 0; j < 512; j++) {

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			if (bitPosition > 1) {
				if ((i + 7) < 90) {
					if ((j & bitMask[bitPosition - 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maRank[i][j], mask[i + 7]);
					}
				}
				if ((i - 11) >= 0) {
					if ((j & bitMask[bitPosition - 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maRank[i][j], mask[i - 11]);
					}
				}
			}
			if (bitPosition < 7) {
				if ((i + 11) < 90) {
					if ((j & bitMask[bitPosition + 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maRank[i][j], mask[i + 11]);
					}
				}
				if ((i - 7) >= 0) {
					if ((j & bitMask[bitPosition + 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maRank[i][j], mask[i - 7]);
					}
				}
			}
		}
		bitPosition = indexRowMapping[i];
		//file movement
		for (j = 0; j < 1024; j++) {

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			if (bitPosition > 0) {
				if ((i + 17) < 90) {
					if ((j & bitMask[bitPosition + 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maFile[i][j], mask[i + 17]);
					}
				}
				if ((i - 19) >= 0) {
					if ((j & bitMask[bitPosition - 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maFile[i][j], mask[i - 19]);
					}
				}
			}
			if (bitPosition < 8) {
				if ((i + 19) < 90) {
					if ((j & bitMask[bitPosition + 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maFile[i][j], mask[i + 19]);
					}
				}
				if ((i - 17) >= 0) {
					if ((j & bitMask[bitPosition - 1]) == 0) {
						BITBOARD_OR(MOVEMENTS.maFile[i][j], mask[i - 17]);
					}
				}
			}
		}
	}
}
void initPaoMovement() {
	int i, k;
	unsigned long j, lowerBits, thisBitMask;
//rank attack
	for (i = 0; i < 9; i++) {
		for (j = 0; j < 512; j++) {
			int bitPosition = i;

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			int bitsToRightBorder = bitPosition;
			int bitsToLeftBorder = 8 - bitsToRightBorder;

			lowerBits = j;
			//looking leftward
			int accessable = 1, attackPositionHaventMarked = 1;
			while (bitsToLeftBorder > 0) {
				thisBitMask = bitMask[9 - bitsToLeftBorder];
				if (accessable) {
					if ((lowerBits & thisBitMask) == 0) {
						lowerBits |= thisBitMask;
					} else {
						lowerBits &= ~thisBitMask;
						accessable = 0;
					}
				} else {
					if ((lowerBits & thisBitMask)
							&& (attackPositionHaventMarked)) {
						attackPositionHaventMarked = 0;
					} else {
						lowerBits &= ~thisBitMask;
					}
				}

				bitsToLeftBorder--;
			}

			//looking rightward
			accessable = 1;
			attackPositionHaventMarked = 1;
			while (bitsToRightBorder > 0) {
				thisBitMask = bitMask[bitsToRightBorder - 1];
				if (accessable) {
					if ((lowerBits & thisBitMask) == 0) {
						lowerBits |= thisBitMask;
					} else {
						lowerBits &= ~thisBitMask;
						accessable = 0;
					}
				} else {
					if ((lowerBits & thisBitMask)
							&& (attackPositionHaventMarked)) {
						lowerBits |= thisBitMask;
						attackPositionHaventMarked = 0;
					} else {
						lowerBits &= ~thisBitMask;
					}
				}
				bitsToRightBorder--;
			}
			lowerBits &= ~bitMask[bitPosition];
			for (k = 0; k < 10; k++) {
				MOVEMENTS.paoRank[i + k * 9][j].startingBits = lowerBits;
				bitBoardLeftShift(&MOVEMENTS.paoRank[i + k * 9][j], k * 9);
			}
		}
	}

	//file attack
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 1024; j++) {
			int bitPosition = i;

			if (BITS_POSITION_NOT_VALID(j,bitPosition))
				continue;

			int bitsToBottomBorder = bitPosition;
			int bitsToTopBorder = 9 - bitsToBottomBorder;

			lowerBits = j;
			//looking upward
			int accessable = 1, attackPositionHaventMarked = 1;
			while (bitsToTopBorder > 0) {
				thisBitMask = bitMask[10 - bitsToTopBorder];
				if (accessable) {
					if ((lowerBits & thisBitMask) == 0) {
						lowerBits |= thisBitMask;
					} else {
						lowerBits &= ~thisBitMask;
						accessable = 0;
					}
				} else {
					if ((lowerBits & thisBitMask)
							&& (attackPositionHaventMarked)) {
						lowerBits |= thisBitMask;
						attackPositionHaventMarked = 0;
					} else {
						lowerBits &= ~thisBitMask;
					}
				}
				bitsToTopBorder--;
			}

			//looking downward
			accessable = 1, attackPositionHaventMarked = 1;
			while (bitsToBottomBorder > 0) {
				thisBitMask = bitMask[bitsToBottomBorder - 1];
				if (accessable) {
					if ((lowerBits & thisBitMask) == 0) {
						lowerBits |= thisBitMask;
					} else {
						lowerBits &= ~thisBitMask;
						accessable = 0;
					}
				} else {
					if ((lowerBits & thisBitMask)
							&& (attackPositionHaventMarked)) {
						attackPositionHaventMarked = 0;
						lowerBits |= thisBitMask;
					} else {
						lowerBits &= ~thisBitMask;
					}
				}
				bitsToBottomBorder--;
			}
			lowerBits &= ~bitMask[bitPosition];
			for (k = 0; k < 9; k++) {
				MOVEMENTS.paoFile[i * 9 + k][j] =
						getFileBitBoardFromLowest10Bits(lowerBits, k);
			}
		}
	}
}

void initBoard() {
	int i, j;
	for (i = 0; i < 90; i++) {
		mask[i].startingBits = 1;
		bitBoardLeftShift(&mask[i], i);
	}
	for (i = 0; i < 9; i++) {
		for (j = 0; j < 10; j++) {
			rotateMask[j * 9 + i].startingBits = 1;
			bitBoardLeftShift(&rotateMask[j * 9 + i], (8 - i) * 10 + j);
		}
	}

	initJiangMovements();
	initShiMovement();
	initXiangMovements();
	initCheMovement();
	initBingMovement();
	initMaMovement();
	initPaoMovement();

//red pieces
	chessPosition.piece_in_square[0] = RC;
	chessPosition.piece_in_square[1] = RM;
	chessPosition.piece_in_square[2] = RX;
	chessPosition.piece_in_square[3] = RS;
	chessPosition.piece_in_square[4] = RJ;
	chessPosition.piece_in_square[5] = RS;
	chessPosition.piece_in_square[6] = RX;
	chessPosition.piece_in_square[7] = RM;
	chessPosition.piece_in_square[8] = RC;

	chessPosition.piece_in_square[19] = RP;
	chessPosition.piece_in_square[25] = RP;

	chessPosition.piece_in_square[27] = RB;
	chessPosition.piece_in_square[29] = RB;
	chessPosition.piece_in_square[31] = RB;
	chessPosition.piece_in_square[33] = RB;
	chessPosition.piece_in_square[35] = RB;

//black pieces
	chessPosition.piece_in_square[81] = BC;
	chessPosition.piece_in_square[82] = BM;
	chessPosition.piece_in_square[83] = BX;
	chessPosition.piece_in_square[84] = BS;
	chessPosition.piece_in_square[85] = BJ;
	chessPosition.piece_in_square[86] = BS;
	chessPosition.piece_in_square[87] = BX;
	chessPosition.piece_in_square[88] = BM;
	chessPosition.piece_in_square[89] = BC;

	chessPosition.piece_in_square[64] = BP;
	chessPosition.piece_in_square[70] = BP;

	chessPosition.piece_in_square[54] = BB;
	chessPosition.piece_in_square[56] = BB;
	chessPosition.piece_in_square[58] = BB;
	chessPosition.piece_in_square[60] = BB;
	chessPosition.piece_in_square[62] = BB;

	for (i = 0; i < 90; i++) {
		switch (chessPosition.piece_in_square[i]) {
		case RB:
			BITBOARD_OR(chessPosition.r_bing, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RS:
			BITBOARD_OR(chessPosition.r_shi, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RX:
			BITBOARD_OR(chessPosition.r_xiang, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RP:
			BITBOARD_OR(chessPosition.r_pao, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RM:
			BITBOARD_OR(chessPosition.r_ma, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RC:
			BITBOARD_OR(chessPosition.r_che, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case RJ:
			BITBOARD_OR(chessPosition.r_jiang, mask[i]);
			BITBOARD_OR(chessPosition.r_pieces, mask[i]);
			break;
		case BB:
			BITBOARD_OR(chessPosition.b_bing, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BS:
			BITBOARD_OR(chessPosition.b_shi, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BX:
			BITBOARD_OR(chessPosition.b_xiang, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BP:
			BITBOARD_OR(chessPosition.b_pao, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BM:
			BITBOARD_OR(chessPosition.b_ma, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BC:
			BITBOARD_OR(chessPosition.b_che, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		case BJ:
			BITBOARD_OR(chessPosition.b_jiang, mask[i]);
			BITBOARD_OR(chessPosition.b_pieces, mask[i]);
			break;
		}
	}
}

BitBoard getRotateBitBoard(BitBoard *board) {
	BitBoard result = { .startingBits = 0, .middleBits = 0, .endingBits = 0 };
	BitBoard temp;
	int i;
	for (i = 0; i < 90; i++) {
		temp = bitBoardAND(board, &mask[i]);
		if (!isBitBoardEmpty(&temp)) {
			BITBOARD_OR(result, rotateMask[i]);
		}
	}
	return result;
}

int genRedJiangKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard jiangPos = chessPos->r_jiang, toPos;
	int fromSquare, toSquare;
	fromSquare = bitBoardLSB(&jiangPos);
	toPos = MOVEMENTS.jiang[fromSquare];
	BITBOARD_AND(toPos, chessPos->b_pieces);
	while (!isBitBoardEmpty(&toPos)) {
		toSquare = bitBoardLSB(&toPos);
		BITBOARD_XOR(toPos, mask[toSquare]);
		movement->from = fromSquare;
		movement->to = toSquare;
		movement++;
		counter++;
	}
	//killing opponent jiang
	int redJiangFile = indexRankBitsPositionMapping[fromSquare];
	int blackJiangPos = bitBoardLSB(&chessPos->b_jiang);
	int blackJiangFile = indexRankBitsPositionMapping[blackJiangPos];
	if (redJiangFile == blackJiangFile) {
		BitBoard rotatedAllPiecesBoard = getRotateBitBoard(
				&chessPos->all_pieces);
		int redJiangRank = indexRowMapping[fromSquare];
		int redJiangRotatedRank = indexRotatedRowMapping[fromSquare];
		int blackJiangRank = indexRowMapping[blackJiangPos];
		unsigned long fileBit = getRotatedBitBoardBitsOfRank(
				redJiangRotatedRank, &rotatedAllPiecesBoard);
		unsigned long betweenMask = 0x78;
		if (fileBit & betweenMask)
			return counter;
		betweenMask = 0x4;
		if (redJiangRank < 2 && (fileBit & betweenMask))
			return counter;
		betweenMask = 0x2;
		if (redJiangRank < 1 && (fileBit & betweenMask))
			return counter;
		betweenMask = 0x80;
		if (blackJiangRank > 7 && (fileBit & betweenMask))
			return counter;
		betweenMask = 0x100;
		if (blackJiangRank > 8 && (fileBit & betweenMask))
			return counter;
		movement->from = fromSquare;
		movement->to = blackJiangPos;
		counter++;
	}
	return counter;
}

int genRedXiangKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard xiangPos = chessPos->r_xiang, toPos, goingTopMovement = {
			.startingBits = 0, .middleBits = 0, .endingBits = 0 },
			goingBottomMovement = { .startingBits = 0, .middleBits = 0,
					.endingBits = 0 };

	int topRow, bottomRow, xiangMappedIndex;
	unsigned long topRowBits, bottomRowBits;

	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&xiangPos)) {
		fromSquare = bitBoardLSB(&xiangPos);
		BITBOARD_XOR(xiangPos, mask[fromSquare]);

		topRow = MOVEMENTS.xiangGoingTopRowMapping[fromSquare];
		bottomRow = MOVEMENTS.xiangGoingBottomRowMapping[fromSquare];

		xiangMappedIndex = MOVEMENTS.xiangIndexMapping[fromSquare];

		if (topRow != INVALID_POS) {
			topRowBits = getBitBoardBitsOfRank(topRow, &chessPos->all_pieces);
			goingTopMovement =
					MOVEMENTS.xiangGoingTop[xiangMappedIndex][topRowBits];
		}
		if (bottomRow != INVALID_POS) {
			bottomRowBits = getBitBoardBitsOfRank(bottomRow,
					&chessPos->all_pieces);
			goingBottomMovement =
					MOVEMENTS.xiangGoingBottom[xiangMappedIndex][bottomRowBits];
		}
		toPos = bitBoardOR(&goingTopMovement, &goingBottomMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genRedShiKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard shiPos = chessPos->r_shi, toPos;
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&shiPos)) {
		fromSquare = bitBoardLSB(&shiPos);
		BITBOARD_XOR(shiPos, mask[fromSquare]);
		toPos = MOVEMENTS.shi[fromSquare];
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genRedBingKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard bingPos = chessPos->r_bing, toPos;
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&bingPos)) {
		fromSquare = bitBoardLSB(&bingPos);
		BITBOARD_XOR(bingPos, mask[fromSquare]);
		toPos = MOVEMENTS.r_bing[fromSquare];
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genRedCheKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard chePos = chessPos->r_che, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&chePos)) {
		fromSquare = bitBoardLSB(&chePos);
		BITBOARD_XOR(chePos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.cheFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.cheRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genRedMaKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard maPos = chessPos->r_ma, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&maPos)) {
		fromSquare = bitBoardLSB(&maPos);
		BITBOARD_XOR(maPos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.maFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.maRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genRedPaoKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard paoPos = chessPos->r_pao, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&paoPos)) {
		fromSquare = bitBoardLSB(&paoPos);
		BITBOARD_XOR(paoPos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.paoFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.paoRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardLSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}

int genBlackJiangKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard jiangPos = chessPos->b_jiang, toPos;
	int fromSquare, toSquare;
	fromSquare = bitBoardMSB(&jiangPos);
	toPos = MOVEMENTS.jiang[fromSquare];
	BITBOARD_AND(toPos, chessPos->b_pieces);
	while (!isBitBoardEmpty(&toPos)) {
		toSquare = bitBoardMSB(&toPos);
		BITBOARD_XOR(toPos, mask[toSquare]);
		movement->from = fromSquare;
		movement->to = toSquare;
		movement++;
		counter++;
	}
	return counter;
}
int genBlackXiangKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard xiangPos = chessPos->b_xiang, toPos, goingTopMovement = {
			.startingBits = 0, .middleBits = 0, .endingBits = 0 },
			goingBottomMovement = { .startingBits = 0, .middleBits = 0,
					.endingBits = 0 };

	int topRow, bottomRow, xiangMappedIndex;

	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&xiangPos)) {
		fromSquare = bitBoardMSB(&xiangPos);
		BITBOARD_XOR(xiangPos, mask[fromSquare]);

		topRow = MOVEMENTS.xiangGoingTopRowMapping[fromSquare];
		bottomRow = MOVEMENTS.xiangGoingBottomRowMapping[fromSquare];
		xiangMappedIndex = MOVEMENTS.xiangIndexMapping[fromSquare];

		if (topRow > 0) {
			goingTopMovement =
					MOVEMENTS.xiangGoingTop[xiangMappedIndex][topRow];
		}
		if (bottomRow > 0) {
			goingBottomMovement =
					MOVEMENTS.xiangGoingBottom[xiangMappedIndex][bottomRow];
		}
		toPos = bitBoardOR(&goingTopMovement, &goingBottomMovement);
		BITBOARD_AND(toPos, chessPos->r_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genBlackShiKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard shiPos = chessPos->b_shi, toPos;
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&shiPos)) {
		fromSquare = bitBoardMSB(&shiPos);
		BITBOARD_XOR(shiPos, mask[fromSquare]);
		toPos = MOVEMENTS.shi[fromSquare];
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genBlackBingKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard bingPos = chessPos->b_bing, toPos;
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&bingPos)) {
		fromSquare = bitBoardMSB(&bingPos);
		BITBOARD_XOR(bingPos, mask[fromSquare]);
		toPos = MOVEMENTS.b_bing[fromSquare];
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genBlackCheKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard chePos = chessPos->b_che, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&chePos)) {
		fromSquare = bitBoardMSB(&chePos);
		BITBOARD_XOR(chePos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.cheFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.cheRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genBlackMaKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard maPos = chessPos->b_ma, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&maPos)) {
		fromSquare = bitBoardMSB(&maPos);
		BITBOARD_XOR(maPos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.maFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.maRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}
int genBlackPaoKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int counter = 0;
	BitBoard paoPos = chessPos->b_pao, toPos, fileMovement, rankMovement,
			currentBoard;
	currentBoard = bitBoardOR(&chessPos->r_pieces, &chessPos->b_pieces);
	BitBoard rotatedBoard = getRotateBitBoard(&currentBoard);
	int fromSquare, toSquare;
	while (!isBitBoardEmpty(&paoPos)) {
		fromSquare = bitBoardMSB(&paoPos);
		BITBOARD_XOR(paoPos, mask[fromSquare]);
		fileMovement =
				MOVEMENTS.paoFile[fromSquare][getRotatedBitBoardBitsOfRank(
						indexRotatedRowMapping[fromSquare], &rotatedBoard)];
		rankMovement = MOVEMENTS.paoRank[fromSquare][getBitBoardBitsOfRank(
				indexRowMapping[fromSquare], &currentBoard)];
		toPos = bitBoardOR(&fileMovement, &rankMovement);
		BITBOARD_AND(toPos, chessPos->b_pieces);
		while (!isBitBoardEmpty(&toPos)) {
			toSquare = bitBoardMSB(&toPos);
			BITBOARD_XOR(toPos, mask[toSquare]);
			movement->from = fromSquare;
			movement->to = toSquare;
			movement++;
			counter++;
		}
	}
	return counter;
}

int genKillingMovements(ChessPosition *chessPos, Movement *movement) {
	int movementPtrPos = 0;
	if (chessPos->player) {
		movementPtrPos += genRedJiangKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedXiangKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedShiKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedBingKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedCheKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedMaKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genRedPaoKillingMovements(chessPos,
				movement + movementPtrPos);
	} else {
		movementPtrPos += genBlackJiangKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackXiangKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackShiKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackBingKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackCheKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackMaKillingMovements(chessPos,
				movement + movementPtrPos);
		movementPtrPos += genBlackPaoKillingMovements(chessPos,
				movement + movementPtrPos);
	}
	return movementPtrPos;
}
int genNoneKillingMovements(ChessPosition *chessPos, Movement *movement) {
//TODO
	return 0;
}
int genJiangEscapeMovements(ChessPosition *chessPos, Movement *movement) {
//TODO
	return 0;
}

void printSinglePiece(int piece) {
	switch (piece) {
	case RB:
		printf("RB");
		break;
	case RS:
		printf("RS");
		break;
	case RX:
		printf("RX");
		break;
	case RP:
		printf("RP");
		break;
	case RM:
		printf("RM");
		break;
	case RC:
		printf("RC");
		break;
	case RJ:
		printf("RJ");
		break;
	case BB:
		printf("BB");
		break;
	case BS:
		printf("BS");
		break;
	case BX:
		printf("BX");
		break;
	case BP:
		printf("BP");
		break;
	case BM:
		printf("BM");
		break;
	case BC:
		printf("BC");
		break;
	case BJ:
		printf("BJ");
		break;
	default:
		printf("--");
		break;
	}
}

void printPiecesPos() {
	int i, j;
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 9; j++) {
//printSinglePiece(chessPosition.pieces[i][j]);
		}
		printf("\n");
	}
}

void printBitBoardBits(BitBoard *board, int chessIndex) {
	int i = 0, j = 0;
	char bits[10][9];
	BitBoard bitAnd;
	for (; i < 10; i++) {
		for (; j < 9; j++) {
			int index = i * 9 + j;
			if (index == chessIndex) {
				bits[i][j] = 'X';
			} else {
				bitAnd = bitBoardAND(board, &mask[index]);
				if (isBitBoardEmpty(&bitAnd)) {
					bits[i][j] = '0';
				} else {
					if (index == chessIndex) {
						bits[i][j] = 'X';
					} else {
						bits[i][j] = '1';
					}
				}
			}
		}
		j = 0;
	}

	for (i = 9; i >= 0; i--) {
		printf("%d | ", i);
		for (j = 8; j >= 0; j--) {
			printf("%c ", bits[i][j]);
		}
		printf("\n");
		j = 8;
	}
	printf("--|-------------------\n");
	printf("  | 8 7 6 5 4 3 2 1 0\n\n");
	fflush(stdout);
}

int main4(void) {
	initBoard();
//	BitBoard b = bitBoardOR(&MOVEMENTS.maRank[39][0xAC],
//			&MOVEMENTS.maFile[39][0x2F5]);
//	printBitBoardBits(&b, 39);

	Movement m[283];
	genKillingMovements(&chessPosition, m);
	return EXIT_SUCCESS;
}

